
import { _decorator, Component, Node, Mesh, utils, MeshRenderer } from 'cc';
import GameConfig from '../../Script/GameSpecial/GameConfig';
import yyComponent from '../../Script/Common/yyComponent';
const { ccclass, property } = _decorator;

@ccclass('SuiDao')
export class SuiDao extends yyComponent {

    public static len: number = 20;
    public static houdu: number = 1;
    protected static meshData;
    protected static _mesh: Mesh;
    protected static get mesh(): Mesh {
        if (!this._mesh) {
            this.createMesh();
        }
        return this._mesh;
    }
    protected static createMesh() {
        this.meshData = {
            positions: [],
            normals: [],
            indices: [],
            uvs: [],
        };
        this.houdu = GameConfig.GameRule.roadHouDu;
        this.houdu = GameConfig.GameRule.roadHouDu / Math.sin(GameConfig.GameRule.roadMaxRadian);//半圆隧道

        let r = GameConfig.GameRule.roadHalfWidth;//半径
        r = GameConfig.GameRule.roadHalfWidth * Math.sin(GameConfig.GameRule.roadMaxRadian);//半圆隧道
        let offsetY = -GameConfig.GameRule.roadHalfWidth * Math.cos(GameConfig.GameRule.roadMaxRadian);//半圆隧道
        // offsetY = 0;

        let radianCount = 21;//圆周上的顶点数量
        let startRadian = -(Math.PI * 0.5 - GameConfig.GameRule.roadMaxRadian);
        let endRadian = Math.PI * 1.5 + GameConfig.GameRule.roadMinRadian;
        startRadian = 0;//半圆隧道
        endRadian = Math.PI;//半圆隧道
        let stepRadian = (endRadian - startRadian) / (radianCount - 1);
        let inPI = 1 / (endRadian - startRadian);
        let startUVx = startRadian * inPI + 0.1;
        let len = this.len;//单个节点的总长度
        let lenCount = 21;//Z轴线上的顶点数量
        let stepZ = len / (lenCount - 1);
        let inLen = 1 / len;
        //内侧表面
        let uvx = 0.5;
        for (let i1 = 0; i1 < radianCount; ++i1) {
            let radian = startRadian + i1 * stepRadian;
            let s1 = Math.sin(radian);
            let c1 = Math.cos(radian);
            let x = r * c1;
            let y = r * s1;
            // let uvx = 0.9 - radian * inPI + startUVx;
            for (let z1 = 0; z1 < lenCount; ++z1) {
                let posZ = z1 * stepZ;
                this.meshData.positions.push(x, y + offsetY, -posZ);
                this.meshData.normals.push(-c1, -s1, 0);
                this.meshData.uvs.push(uvx, 1 - posZ * inLen);
            }
        }
        for (let rc = 0; rc < radianCount - 1; ++rc) {
            for (let z2 = 0; z2 < lenCount - 1; ++z2) {
                let i2 = rc * lenCount + z2;
                this.meshData.indices.push(i2, i2 + lenCount, i2 + 1, i2 + 1, i2 + lenCount, i2 + lenCount + 1);
            }
        }

        //外侧表面
        r += this.houdu;
        for (let i3 = 0; i3 < radianCount; ++i3) {
            let radian = startRadian + i3 * stepRadian;
            let s2 = Math.sin(radian);
            let c2 = Math.cos(radian);
            let x = r * c2;
            let y = r * s2;
            // let uvx = 0.9 - radian * inPI + startUVx;
            for (let z3 = 0; z3 < lenCount; ++z3) {
                let posZ = z3 * stepZ;
                this.meshData.positions.push(x, y + offsetY, -posZ);
                this.meshData.normals.push(c2, s2, 0);
                this.meshData.uvs.push(uvx, 1 - posZ * inLen);
            }
        }
        let offset = radianCount * lenCount;
        for (let rc = 0; rc < radianCount - 1; ++rc) {
            for (let z4 = 0; z4 < lenCount - 1; ++z4) {
                let i4 = rc * lenCount + z4 + offset;
                this.meshData.indices.push(i4 + 1, i4 + lenCount, i4, i4 + 1, i4 + lenCount + 1, i4 + lenCount);
            }
        }

        //端面
        let posOffset = lenCount;
        let positions = this.meshData.positions;
        let uv = 0.5;
        for (let i4 = 0; i4 < radianCount; ++i4) {
            let index = posOffset * i4 * 3;
            positions.push(positions[index++], positions[index++], positions[index++]);
            index = posOffset * i4 * 3 + offset * 3;
            positions.push(positions[index++], positions[index++], positions[index++]);
            this.meshData.normals.push(0, 0, 1, 0, 0, 1);
            this.meshData.uvs.push(uv, uv, uv, uv);
        }
        offset *= 2;
        for (let rc = 0; rc < radianCount - 1; ++rc) {
            let i = offset + rc * 2;
            this.meshData.indices.push(i, i + 1, i + 2, i + 1, i + 3, i + 2);
        }

        this._mesh = new Mesh();
        this._mesh = utils.createMesh(this.meshData);
    }


    protected initSub() {
        this.initMesh();
    }

    @property(MeshRenderer)
    protected meshRender: MeshRenderer = null;
    protected initMesh() {
        this.meshRender.mesh = SuiDao.mesh;
    }


}

